/*
  The MIT License
  
  Copyright (c) 2010 smath-view project
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
package pl.smath.renderer.demo;

import pl.smath.expression.model.Term;
import pl.smath.expression.parser.ExpressionParser;
import pl.smath.expression.parser.ExpressionParserException;
import pl.smath.renderer.renderer.TermRendererException;
import pl.smath.renderer.renderer.TermWidgetFactory;
import pl.smath.renderer.utils.InteractionManager;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.xml.client.impl.DOMParseException;



/**
 * Demo module fo testing rendering
 * 
 * @author Damian Rodziewicz
 * @author Krzysztof Langner
 */
public class ExamplesEntryPoint implements EntryPoint {
	
	private final FlexTable termTable = new FlexTable();
	private final VerticalPanel mainPanel = new VerticalPanel();
	private final HorizontalPanel addPanel = new HorizontalPanel();
	private final TextBox newSymbolTextBox = new TextBox();
	private final Button addTermButton = new Button("Add");
	private final Label expressionLabel = new Label();

	private final TermWidgetFactory termWidgetFactory = new TermWidgetFactory();
	private final ExpressionParser parser = new ExpressionParser();
	private final String[] sampleExpressions = {
			"-(32+52-(25+(42-54)))",
			"-(2*(1+21)*5+(4*-23+4)*(14-2*-(3+1)))*143",
			"-(-(1/(3$2)+4))$(1/2)", 
			"(15*x*5+x$3)/((1+(16*w+1/(2$3))$(-(5*1/((1/2*5*z-14)$(4))))))",
	};

	
	/**
	 * entry point on load 
	 */
	public void onModuleLoad() {
		
		RootPanel.get("view").add(mainPanel);
		
		termWidgetFactory.setFontHeight("22px");
		
		// Assemble Add Stock panel.
		addPanel.add(newSymbolTextBox);
		addPanel.add(addTermButton);
		addPanel.add(expressionLabel);
		
	    // Assemble Main panel.
	    mainPanel.add(addPanel);
	    mainPanel.add(termTable);
	    
	    // Move cursor focus to the input box.
	    newSymbolTextBox.setFocus(true);
	    
		termTable.setText(0, 0, "Expression");
		termTable.setText(0, 1, "Rendered canvas");
		
		// Listen for mouse events on the Add button.
	    addTermButton.addClickHandler(new ClickHandler() {
	      public void onClick(ClickEvent event) {
	    	  addTerm(newSymbolTextBox.getText());
	  			newSymbolTextBox.setText("");
	      }  
	    });
	    
	    // Listen for keyboard events in the input box.
	    newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
	      public void onKeyPress(KeyPressEvent event) {
	        if (event.getCharCode() == KeyCodes.KEY_ENTER) {
	        	addTerm(newSymbolTextBox.getText());
	    		newSymbolTextBox.setText("");
			}
	      }
	    });
	    
	    
	    newSymbolTextBox.addKeyUpHandler(new KeyUpHandler() {
			
			public void onKeyUp(KeyUpEvent event) {
				onEntryBoxChange(newSymbolTextBox.getText());
			}
		});
	    
	    
		for (String expression : sampleExpressions) {
			addTerm(expression);
		}
	}
	
	
	/**
	 * Add term to FlexTable. Executed when the user clicks the addTermButton or
	 * presses enter in the newSymbolTextBox.
	 */
	private void addTerm(String symbol) {    
	
		Term term = null;
		FlowPanel owner = new FlowPanel();
		InteractionManager rm = new InteractionManager(owner);
		
		//aboveLayer.add(new Label("lable1"), 20, 10);

		Integer rows = termTable.getRowCount();
		Integer row = rows+1;
		termTable.setText(row, 0, symbol);
		termTable.setWidget(row, 1, owner);	
		  
		try {
			term  = null;
			if (symbol.indexOf("<") == -1  ||  symbol.indexOf(">") == -1)
				term = parser.parseText(symbol);
			else 
				term = parser.parseMathML(symbol);
			termWidgetFactory.createWidget(term, rm);
			rm.process();
		} catch (ExpressionParserException e) {
			term = null;
			termTable.remove(owner);
			termTable.setText(row, 1, "error while parsing text");
			return;
		} catch (TermRendererException e) {
			termTable.remove(owner);
			termTable.setText(row, 1, "error while rendering term");
			return;
		}		  
	  
		newSymbolTextBox.setFocus(true);
	

		for (int i = 0 ; i < rm.getGapsCount() ; i ++){
			rm.getGapAt(i).setText(String.valueOf(i));
		}
	}
	
	
	/**
	 * Renderowanie wyrazenia podczas jego wprowadzania
	 * @param text
	 */
	private void onEntryBoxChange(String text) {

		FlowPanel owner = new FlowPanel();
		InteractionManager rm = new InteractionManager(owner);
		addPanel.remove(2);
		addPanel.add(owner);

		try {
			addTermButton.setEnabled(true);
			Term term  = null;
			if (text.indexOf("<") == -1  ||  text.indexOf(">") == -1)
				term = parser.parseText(text);
			else 
				term = parser.parseMathML(text);
			termWidgetFactory.createWidget(term, rm);			
			rm.process();
		} catch (ExpressionParserException e) {
			addTermButton.setEnabled(false);
			expressionLabel.setText(e.getMessage());
		}  catch (DOMParseException e) {
			addTermButton.setEnabled(false);
			expressionLabel.setText(e.getMessage());
		} catch (TermRendererException e) {
			expressionLabel.setText(e.getMessage());
		}		  
	}

	
}
